package oo

import (
	"ai-curd/controller/response"
	"ai-curd/oo/primitive"
)

type Users []User

type User interface {
	ID() int
	IDIsPresent(f func(v int))
	SetID(id int)

	Category() int
	CategoryIsPresent(f func(v int))
	SetCategory(v int)

	Level() int
	LevelIsPresent(f func(v int))
	SetLevel(v int)

	Phone() string
	PhoneIsPresent(f func(v string))
	SetPhone(v string)

	Nickname() string
	NicknameIsPresent(f func(v string))
	SetNickname(v string)

	Mapper() *response.User
}

type baseUser struct {
	id       primitive.ID
	category primitive.Int
	level    primitive.Int
	phone    primitive.String
	nickname primitive.String
}

func (u *baseUser) ID() int {
	return u.id.Value()
}

func (u *baseUser) IDIsPresent(f func(v int)) {
	u.id.IsPresent(f)
}

func (u *baseUser) SetID(id int) {
	u.id.SetValue(id)
}

func (u *baseUser) Category() int {
	return u.category.Value()
}

func (u *baseUser) CategoryIsPresent(f func(v int)) {
	u.category.IsPresent(f)
}

func (u *baseUser) SetCategory(v int) {
	u.category.SetValue(v)
}

func (u *baseUser) Level() int {
	return u.level.Value()
}

func (u *baseUser) LevelIsPresent(f func(v int)) {
	u.level.IsPresent(f)
}

func (u *baseUser) SetLevel(v int) {
	u.level.SetValue(v)
}

func (u *baseUser) Phone() string {
	return u.phone.Value()
}

func (u *baseUser) PhoneIsPresent(f func(v string)) {
	u.phone.IsPresent(f)
}

func (u *baseUser) SetPhone(v string) {
	u.phone.SetValue(v)
}

func (u *baseUser) Nickname() string {
	return u.nickname.Value()
}

func (u *baseUser) NicknameIsPresent(f func(v string)) {
	u.nickname.IsPresent(f)
}

func (u *baseUser) SetNickname(v string) {
	u.nickname.SetValue(v)
}

func (u *baseUser) Mapper() *response.User {
	return &response.User{
		ID:       u.ID(),
		Category: u.Category(),
		Phone:    u.Phone(),
		Nickname: u.Nickname(),
	}
}

type NormalUser struct {
	baseUser
}

func NewUser(category int) User {
	u := &NormalUser{}
	u.SetCategory(category)
	return u
}

func (oo Users) Mapper() response.Users {
	size := len(oo)
	respUsers := make(response.Users, size)
	for i := 0; i < size; i++ {
		respUsers[i] = oo[i].Mapper()
	}
	return respUsers
}
